import { ref } from 'vue';

// 保存请求日志的状态
const requestLogs = ref([]);
const isLoggerMinimized = ref(true);
const isLoggerVisible = ref(false);
const MAX_LOGS = 50;

/**
 * 请求日志监控 Composable
 * @param {Object} options 配置选项
 * @param {Array<'xhr'|'fetch'|'uni'>} options.environments 需要监控的请求环境
 * @returns {Object} 请求日志相关的状态和方法
 */
export function useRequestLogger(options = { environments: ['xhr'], show: false }) {
  console.log(options)
  if (options.show){
    isLoggerVisible.value = true;
  } else {
    isLoggerVisible.value = false;
  }
  /**
   * 记录请求日志
   * @param {Object} log 请求日志对象
   */
  const logRequest = (log) => {
    // 添加时间戳
    log.timestamp = new Date().toLocaleTimeString();
    
    // 将新日志添加到数组开头
    requestLogs.value.unshift(log);
    
    // 控制日志数量，防止内存泄漏
    if (requestLogs.value.length > MAX_LOGS) {
      requestLogs.value.pop();
    }
  };

  /**
   * 清空日志
   */
  const clearLogs = () => {
    requestLogs.value = [];
  };

  /**
   * 切换最小化状态
   */
  const toggleMinimize = () => {
    isLoggerMinimized.value = !isLoggerMinimized.value;
  };

  /**
   * 切换可见性
   */
  const toggleVisibility = () => {
    isLoggerVisible.value = !isLoggerVisible.value;
  };

  /**
   * 格式化请求参数展示
   * @param {Object} data 请求数据
   * @returns {String} 格式化后的字符串
   */
  const formatData = (data) => {
    try {
      return JSON.stringify(data, null, 2);
    } catch (e) {
      return String(data);
    }
  };

  /**
   * 初始化XHR请求拦截器
   */
  const initXHRInterceptor = () => {
    const XHR = XMLHttpRequest.prototype;
    const open = XHR.open;
    const send = XHR.send;

    XHR.open = function (method, url) {
      this._requestLog = {
        id: Date.now().toString(),
        url,
        method,
        startTime: Date.now(),
        status: 'pending',
        type: 'xhr'
      };
      return open.apply(this, arguments);
    };

    XHR.send = function (data) {
      if (this._requestLog) {
        this._requestLog.requestData = data;

        this.addEventListener('load', () => {
          const response = this.responseType === 'json' ? this.response : this.responseText;
          this._requestLog.status = this.status >= 200 && this.status < 300 ? 'success' : 'failed';
          this._requestLog.endTime = Date.now();
          this._requestLog.duration = this._requestLog.endTime - this._requestLog.startTime;
          this._requestLog.responseData = response;
          this._requestLog.statusCode = this.status;
          logRequest(this._requestLog);
        });

        this.addEventListener('error', (error) => {
          this._requestLog.status = 'failed';
          this._requestLog.endTime = Date.now();
          this._requestLog.duration = this._requestLog.endTime - this._requestLog.startTime;
          this._requestLog.error = 'Network Error';
          this._requestLog.errorDetails = error;
          logRequest(this._requestLog);
        });
      }
      return send.apply(this, arguments);
    };
  };

  /**
   * 初始化Fetch请求拦截器
   */
  const initFetchInterceptor = () => {
    const originalFetch = window.fetch;
    window.fetch = async function (input, init = {}) {
      const requestLog = {
        id: Date.now().toString(),
        url: typeof input === 'string' ? input : input.url,
        method: (init.method || (typeof input === 'string' ? 'GET' : input.method) || 'GET').toUpperCase(),
        requestHeaders: init.headers || {},
        requestData: init.body,
        startTime: Date.now(),
        status: 'pending',
        type: 'fetch'
      };

      try {
        const response = await originalFetch.apply(this, arguments);
        const clonedResponse = response.clone();
        
        requestLog.status = response.ok ? 'success' : 'failed';
        requestLog.endTime = Date.now();
        requestLog.duration = requestLog.endTime - requestLog.startTime;
        requestLog.statusCode = response.status;
        
        try {
          requestLog.responseData = await clonedResponse.json();
        } catch {
          requestLog.responseData = await clonedResponse.text();
        }
        
        logRequest(requestLog);
        return response;
      } catch (error) {
        requestLog.status = 'failed';
        requestLog.endTime = Date.now();
        requestLog.duration = requestLog.endTime - requestLog.startTime;
        requestLog.error = error.message;
        requestLog.errorDetails = error;
        logRequest(requestLog);
        throw error;
      }
    };
  };

  /**
   * 初始化Uni请求拦截器
   */
  const initUniInterceptor = () => {
    const originalRequest = uni.request;
    uni.request = function (options) {
      // 记录请求开始信息
      const requestLog = {
        id: options.header?.unique_request_id || Date.now().toString(),
        url: options.url,
        method: options.method || 'GET',
        requestData: options.data,
        requestHeaders: options.header,
        startTime: Date.now(),
        status: 'pending'
      };
      
      // 修改原始成功回调
      const originalSuccess = options.success;
      options.success = (res) => {
        // 更新请求日志 - 成功
        requestLog.status = 'success';
        requestLog.endTime = Date.now();
        requestLog.duration = requestLog.endTime - requestLog.startTime;
        requestLog.responseData = res.data;
        requestLog.statusCode = res.statusCode;
        logRequest(requestLog);
        
        // 调用原始回调
        if (originalSuccess) {
          originalSuccess(res);
        }
      };
      
      // 修改原始失败回调
      const originalFail = options.fail;
      options.fail = (err) => {
        // 更新请求日志 - 失败
        requestLog.status = 'failed';
        requestLog.endTime = Date.now();
        requestLog.duration = requestLog.endTime - requestLog.startTime;
        requestLog.error = err.errMsg || err.msg || err.message || '网络错误！';
        requestLog.errorDetails = err;
        logRequest(requestLog);
        
        // 调用原始回调
        if (originalFail) {
          originalFail(err);
        }
      };
      
      // 调用原始请求方法
      return originalRequest.call(this, options);
    };
  };

  /**
   * 初始化所有配置的请求拦截器
   */
  const initRequestInterceptor = () => {
    const { environments = ['uni'] } = options;

    if (environments.includes('xhr') && typeof XMLHttpRequest !== 'undefined') {
      initXHRInterceptor();
    }
    
    if (environments.includes('fetch') && typeof window !== 'undefined' && window.fetch) {
      initFetchInterceptor();
    }
    
    if (environments.includes('uni') && typeof uni !== 'undefined') {
      initUniInterceptor();
    }
  };

  return {
    requestLogs,
    isLoggerMinimized,
    isLoggerVisible,
    logRequest,
    clearLogs,
    toggleMinimize,
    toggleVisibility,
    formatData,
    initRequestInterceptor,
    environment: options.environment
  };
}